package com.xyht.medicine_management_system.modules.payment.util;

import com.alipay.api.domain.RoyaltyDetail;
import com.alipay.api.response.*;
import com.baomidou.mybatisplus.extension.api.R;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.payments.app.model.*;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.profitsharing.model.*;
import com.wechat.pay.java.service.refund.model.*;
import com.xyht.medicine_management_system.common.util.TimeUtil;
import com.xyht.medicine_management_system.modules.payment.alipay.util.AliPayUtil;
import com.xyht.medicine_management_system.modules.payment.entity.OrderQueryResponse;
import com.xyht.medicine_management_system.modules.payment.entity.ProfitSharingResponse;
import com.xyht.medicine_management_system.modules.payment.entity.RefundResponse;
import com.xyht.medicine_management_system.modules.payment.wxpay.config.WxPayConfig;
import com.xyht.medicine_management_system.modules.payment.wxpay.entity.CallbackPayResourceEntity;
import com.xyht.medicine_management_system.modules.payment.wxpay.entity.PrepayPaymentReq;
import com.xyht.medicine_management_system.modules.payment.wxpay.entity.RefundReq;
import com.xyht.medicine_management_system.modules.payment.wxpay.util.WxPayUtil;
import org.apache.commons.codec.binary.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

import java.math.BigDecimal;

import static com.xyht.medicine_management_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.medicine_management_system.modules.payment.constant.CommonConstant.WX_MERCHANT_ID;
import static com.xyht.medicine_management_system.modules.payment.constant.CommonConstant.WX_NOTIFY_PAY_CALLBACK;
import static com.xyht.medicine_management_system.modules.payment.constant.PaymentMethodConstant.PAYMENT_METHOD_ALI;
import static com.xyht.medicine_management_system.modules.payment.constant.PaymentMethodConstant.PAYMENT_METHOD_WX;
import static com.xyht.medicine_management_system.modules.payment.constant.ProfitSharingStatusConstant.*;

@Component
public class PaymentUtil {
    @Resource
    private WxPayUtil wxPayUtil;
    @Resource
    private AliPayUtil aliPayUtil;


    /**
     * @description 订单预支付 生成预支付码给前端
     * @create 2023/12/21
     * @author dxn
     */
    public String prepayPayment(PrepayPaymentReq prepayPaymentReq) {
        if (isNullOrEmpty(prepayPaymentReq.getOutTradeNo(), prepayPaymentReq.getDescription(),
                prepayPaymentReq.getTimeExpire(), prepayPaymentReq.getTotal(),
                prepayPaymentReq.getPaymentMethod())) {
            return null;
        }
        String prepay_id;
        if (prepayPaymentReq.getPaymentMethod().equals(PAYMENT_METHOD_WX)) {
            prepay_id = wxPayUtil.prepayPayment(prepayPaymentReq);
        } else if (prepayPaymentReq.getPaymentMethod().equals(PAYMENT_METHOD_ALI)) {
            prepay_id = aliPayUtil.prepayPayment(prepayPaymentReq);
        } else {
            return null;
        }
        return prepay_id;
    }


    /**
     * @param order_id 订单号
     * @description 订单状态查询
     * @create 2023/12/24
     * @author dxn
     */
    public OrderQueryResponse queryOrderByOutTradeNo(String order_id, String payment_method) {
        OrderQueryResponse orderQueryResponse = new OrderQueryResponse();
        if (payment_method.equals(PAYMENT_METHOD_WX)) {
            Transaction transaction = wxPayUtil.queryOrderByOutTradeNo(order_id);
            if (transaction == null || !transaction.getTradeState().equals(Transaction.TradeStateEnum.SUCCESS)) {
                return null;
            }
            orderQueryResponse.setTotal(transaction.getAmount().getTotal());
            orderQueryResponse.setSuccessTime(TimeUtil.rfc3339ParseDate(transaction.getSuccessTime()));
            orderQueryResponse.setTransactionId(transaction.getTransactionId());
        } else if (payment_method.equals(PAYMENT_METHOD_ALI)) {
            AlipayTradeQueryResponse alipayTradeQueryResponse = aliPayUtil.queryOrderByOutTradeNo(order_id);
            if (alipayTradeQueryResponse == null || !alipayTradeQueryResponse.getTradeStatus().equals("TRADE_SUCCESS")) {
                return null;
            }
            double totalDouble = Double.parseDouble(alipayTradeQueryResponse.getTotalAmount());
            int total = BigDecimal.valueOf(totalDouble).multiply(new BigDecimal(100)).intValue();
            orderQueryResponse.setTotal(total);
            orderQueryResponse.setSuccessTime(alipayTradeQueryResponse.getSendPayDate());
            orderQueryResponse.setTransactionId(alipayTradeQueryResponse.getTradeNo());
        } else {
            return null;
        }
        return orderQueryResponse;
    }

    /**
     * @description 用户退款
     * @create 2023/12/24
     * @author dxn
     */
    public RefundResponse createRefund(RefundReq refundReq) {
        RefundResponse refundResponse = new RefundResponse();
        if (refundReq.getPaymentMethod().equals(PAYMENT_METHOD_WX)) {
            Refund refund = wxPayUtil.createRefund(refundReq);
            if (refund == null || !refund.getStatus().equals(Status.SUCCESS)) {
                return null;
            }
            refundResponse.setRefundTradeId(refund.getRefundId());
            refundResponse.setSuccessTime(TimeUtil.rfc3339ParseDate(refund.getSuccessTime()));
            refundResponse.setTotal(Integer.valueOf(refund.getAmount().getRefund().toString()));
            refundResponse.setOutTradeNo(refund.getOutTradeNo());
        } else if (refundReq.getPaymentMethod().equals(PAYMENT_METHOD_ALI)) {
            AlipayTradeRefundResponse alipayTradeQueryResponse = aliPayUtil.createRefund(refundReq);
            if (alipayTradeQueryResponse == null) {
                return null;
            }
            double totalDouble = Double.parseDouble(alipayTradeQueryResponse.getRefundFee());
            int totalInt = BigDecimal.valueOf(totalDouble).multiply(new BigDecimal(100)).intValue();
            refundResponse.setSuccessTime(alipayTradeQueryResponse.getGmtRefundPay());
            refundResponse.setTotal(totalInt);
            refundResponse.setRefundTradeId(alipayTradeQueryResponse.getTradeNo());
            refundResponse.setOutTradeNo(alipayTradeQueryResponse.getOutTradeNo());
        } else {
            return null;
        }
        return refundResponse;
    }

    /**
     * @param refund_id 退款单号
     * @description 用户退款查询
     * @create 2023/12/25
     * @author dxn
     */
    public RefundResponse queryByOutRefundNo(String refund_id, String payment_method) {
        if (isNullOrEmpty(payment_method)) {
            return null;
        }
        RefundResponse refundResponse = new RefundResponse();
        if (payment_method.equals(PAYMENT_METHOD_WX)) {
            Refund refund = wxPayUtil.queryByOutRefundNo(refund_id);
            if (refund == null || !refund.getStatus().equals(Status.SUCCESS)) {
                return null;
            }
            refundResponse.setRefundTradeId(refund.getRefundId());
            refundResponse.setSuccessTime(TimeUtil.rfc3339ParseDate(refund.getSuccessTime()));
            refundResponse.setTotal(Integer.valueOf(refund.getAmount().getRefund().toString()));
            refundResponse.setOutTradeNo(refund.getOutTradeNo());
        } else if (payment_method.equals(PAYMENT_METHOD_ALI)) {
            AlipayTradeFastpayRefundQueryResponse alipayTradeQueryResponse = aliPayUtil.queryByOutRefundNo(refund_id);
            if (alipayTradeQueryResponse == null || !alipayTradeQueryResponse.getRefundStatus().equals("REFUND_SUCCESS")) {
                return null;
            }
            double totalDouble = Double.parseDouble(alipayTradeQueryResponse.getRefundAmount());
            int totalInt = BigDecimal.valueOf(totalDouble).multiply(new BigDecimal(100)).intValue();
            refundResponse.setSuccessTime(alipayTradeQueryResponse.getGmtRefundPay());
            refundResponse.setTotal(totalInt);
            refundResponse.setRefundTradeId(alipayTradeQueryResponse.getTradeNo());
            refundResponse.setOutTradeNo(alipayTradeQueryResponse.getOutTradeNo());
        } else {
            return null;
        }
        return refundResponse;
    }

    /**
     * @param profitSharing_id 分账单号
     * @param transaction_id   平台订单号
     * @description 分账完结解除冻结
     * @create 2023/12/25
     * @author dxn
     */
    public void profitSharingUnfreezeOrder(String profitSharing_id, String transaction_id, String payment_method) {
        if (payment_method.equals(PAYMENT_METHOD_WX)) {
            wxPayUtil.profitSharingUnfreezeOrder(profitSharing_id, transaction_id);
        } else if (payment_method.equals(PAYMENT_METHOD_ALI)) {
            aliPayUtil.profitSharingUnfreezeOrder(profitSharing_id, transaction_id);
        }
    }

    /**
     * @param profitSharing_id 订单号
     * @param transaction_id   微信订单号
     * @description 分账结果查询
     * @create 2023/12/25
     * @author dxn
     */
    public ProfitSharingResponse profitSharingQueryOrder(String profitSharing_id, String transaction_id, String payment_method) {
        ProfitSharingResponse profitSharingResponse = new ProfitSharingResponse();
        if (payment_method.equals(PAYMENT_METHOD_WX)) {
            OrdersEntity ordersEntity = wxPayUtil.profitSharingQueryOrder(profitSharing_id, transaction_id);
            if (ordersEntity.getReceivers() == null || ordersEntity.getReceivers().get(0) == null) {
                return null;
            }
            OrderReceiverDetail detail = ordersEntity.getReceivers().get(0);
            if (detail.getResult().equals(DetailStatus.SUCCESS)) {
                profitSharingResponse.setStatus(PROFIT_SHARING_SUCCESS);
            } else if (detail.getResult().equals(DetailStatus.CLOSED)) {
                profitSharingResponse.setStatus(PROFIT_SHARING_FAIL);
            } else if (detail.getResult().equals(DetailStatus.PENDING)) {
                profitSharingResponse.setStatus(PROFIT_SHARING_PROCESSING);
            }
        } else if (payment_method.equals(PAYMENT_METHOD_ALI)) {
            AlipayTradeOrderSettleQueryResponse response = aliPayUtil.profitSharingQueryOrder(profitSharing_id, transaction_id);
            if (response.getRoyaltyDetailList() == null || response.getRoyaltyDetailList().get(0) == null) {
                return null;
            }
            RoyaltyDetail detail = response.getRoyaltyDetailList().get(0);
            if (detail.getState().equals("SUCCESS")) {
                profitSharingResponse.setStatus(PROFIT_SHARING_SUCCESS);
            } else if (detail.getState().equals("FAIL")) {
                profitSharingResponse.setStatus(PROFIT_SHARING_FAIL);
            } else if (detail.getState().equals("PROCESSING")) {
                profitSharingResponse.setStatus(PROFIT_SHARING_PROCESSING);
            }
        }
        return profitSharingResponse;
    }


}
